﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Gmantis.Controls.Automation;

namespace Gmantis.Controls.TileView
{
    public class TileView : System.Windows.Controls.ItemsControl
    {
        // Fields
        internal bool _isLoaded;
        private AutomationPeer _peer;
        private bool _throwMaximizedIndexChanged = true;
        private bool _throwMaximizedItemChanged = true;
        public static readonly DependencyProperty AnimationDurationProperty = DependencyProperty.Register("AnimationDuration", typeof(TimeSpan), typeof(TileView), new PropertyMetadata(TimeSpan.FromSeconds(0.33333333333333331)));
        public static readonly DependencyProperty AnimationEasingFunctionProperty = DependencyProperty.Register("AnimationEasingFunction", typeof(IEasingFunction), typeof(TileView), new PropertyMetadata(new QuadraticEase()));
        public static readonly DependencyProperty ButtonBackgroundProperty = DependencyProperty.Register("ButtonBackground", typeof(Brush), typeof(TileView), null);
        public static readonly DependencyProperty ButtonForegroundProperty = DependencyProperty.Register("ButtonForeground", typeof(Brush), typeof(TileView), null);
        public static readonly DependencyProperty CanUserReorderProperty = DependencyProperty.Register("CanUserReorder", typeof(bool), typeof(TileView), new PropertyMetadata(true));
        public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register("Columns", typeof(int), typeof(TileView), new PropertyMetadata(0, new PropertyChangedCallback(TileView.OnColumnsPropertyChanged)));
        public static readonly DependencyProperty FocusBrushProperty = DependencyProperty.Register("FocusBrush", typeof(Brush), typeof(TileView), null);
        internal int GrabbedIndex = -1;
        internal Rect? GrabbedLastRect;
        public static readonly DependencyProperty HeaderBackgroundProperty = DependencyProperty.Register("HeaderBackground", typeof(Brush), typeof(TileView), null);
        public static readonly DependencyProperty HeaderForegroundProperty = DependencyProperty.Register("HeaderForeground", typeof(Brush), typeof(TileView), null);
        public static readonly DependencyProperty ItemBackgroundProperty = DependencyProperty.Register("ItemBackground", typeof(Brush), typeof(TileView), null);
        public static readonly DependencyProperty ItemForegroundProperty = DependencyProperty.Register("ItemForeground", typeof(Brush), typeof(TileView), null);
        public static readonly DependencyProperty ItemTemplateHeaderProperty = DependencyProperty.Register("ItemTemplateHeader", typeof(DataTemplate), typeof(TileView), null);
        public static readonly DependencyProperty ItemTemplateHeaderSelectorProperty = DependencyProperty.Register("ItemTemplateHeaderSelector", typeof(DataTemplateSelector), typeof(TileView), new PropertyMetadata(null));
        public static readonly DependencyProperty ItemTemplateMaximizedProperty = DependencyProperty.Register("ItemTemplateMaximized", typeof(DataTemplate), typeof(TileView), null);
        public static readonly DependencyProperty ItemTemplateMaximizedSelectorProperty = DependencyProperty.Register("ItemTemplateMaximizedSelector", typeof(DataTemplateSelector), typeof(TileView), new PropertyMetadata(null));
        public static readonly DependencyProperty ItemTemplateMinimizedProperty = DependencyProperty.Register("ItemTemplateMinimized", typeof(DataTemplate), typeof(TileView), null);
        public static readonly DependencyProperty ItemTemplateMinimizedSelectorProperty = DependencyProperty.Register("ItemTemplateMinimizedSelector", typeof(DataTemplateSelector), typeof(TileView), new PropertyMetadata(null));
        public static readonly DependencyProperty ItemTemplateSelectorProperty = DependencyProperty.Register("ItemTemplateSelector", typeof(DataTemplateSelector), typeof(TileView), new PropertyMetadata(null));
        public static readonly DependencyProperty MaximizedIndexProperty = DependencyProperty.Register("MaximizedIndex", typeof(int), typeof(TileView), new PropertyMetadata(-1, new PropertyChangedCallback(TileView.OnMaximizedIndexPropertyChanged)));
        public static readonly DependencyProperty MaximizedItemProperty = DependencyProperty.Register("MaximizedItem", typeof(object), typeof(TileView), new PropertyMetadata(new PropertyChangedCallback(TileView.OnMaximizedItemPropertyChanged)));
        public static readonly DependencyProperty MinimizedItemsPositionProperty = DependencyProperty.Register("MinimizedItemsPosition", typeof(Dock), typeof(TileView), new PropertyMetadata(Dock.Right, new PropertyChangedCallback(TileView.OnMinimizedItemsPositionPropertyChanged)));
        public static readonly DependencyProperty MouseOverBrushProperty = DependencyProperty.Register("MouseOverBrush", typeof(Brush), typeof(TileView), null);
        internal TileViewPanel Panel;
        public static readonly DependencyProperty PressedBrushProperty = DependencyProperty.Register("PressedBrush", typeof(Brush), typeof(TileView), null);
        internal Ranking Ranking = new Ranking();
        public static readonly DependencyProperty RowsProperty = DependencyProperty.Register("Rows", typeof(int), typeof(TileView), new PropertyMetadata(0, new PropertyChangedCallback(TileView.OnRowsPropertyChanged)));
        internal const float ScaleThreshold = 0.1f;
        public static readonly DependencyProperty ScrollBarStyleProperty = DependencyProperty.Register("ScrollBarStyle", typeof(Style), typeof(TileView), new PropertyMetadata(new PropertyChangedCallback(TileView.OnScrollBarStylePropertyChanged)));
        public static readonly DependencyProperty ScrollBarVisibilityProperty = DependencyProperty.Register("ScrollBarVisibility", typeof(ScrollBarVisibility), typeof(TileView), new PropertyMetadata(ScrollBarVisibility.Auto, new PropertyChangedCallback(TileView.OnScrollBarVisibilityPropertyChanged)));
        internal bool ShouldAnimate;
        public static readonly DependencyProperty UpdateSourceCollectionProperty = DependencyProperty.Register("UpdateSourceCollection", typeof(bool), typeof(TileView), new PropertyMetadata(true));

        // Events
        public event EventHandler<PropertyChangedEventArgs<int>> MaximizedIndexChanged;

        public event EventHandler<PropertyChangedEventArgs<object>> MaximizedItemChanged;

        // Methods
        public TileView()
        {
            base.DefaultStyleKey = typeof(TileView);
            SetCustomDefaultValues();
        }

        protected override void ClearContainerForItemOverride(DependencyObject element, object item)
        {
            base.ClearContainerForItemOverride(element, item);
            TileViewItem item2 = (TileViewItem)element;
            item2.isPrepared = false;
            item2.TileView = null;
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new TileViewItem();
        }

        private DataTemplate GetItemDataTemplate(TileViewItem tileViewItem, object item)
        {
            object obj2 = (tileViewItem == item) ? tileViewItem.Header : item;
            DataTemplate itemTemplate = null;
            if (this.ItemTemplateSelector != null)
            {
                itemTemplate = this.ItemTemplateSelector.SelectTemplate(obj2, tileViewItem);
            }
            if (base.ItemTemplate != null)
            {
                itemTemplate = base.ItemTemplate;
            }
            if (tileViewItem == item)
            {
                if (tileViewItem.ContentTemplateSelector != null)
                {
                    itemTemplate = tileViewItem.ContentTemplateSelector.SelectTemplate(obj2, tileViewItem);
                }
                if (tileViewItem.ContentTemplate != null)
                {
                    itemTemplate = tileViewItem.ContentTemplate;
                }
            }
            return itemTemplate;
        }

        private DataTemplate GetItemHeaderDataTemplate(TileViewItem tileViewItem, object item)
        {
            object obj2 = (tileViewItem == item) ? tileViewItem.Content : item;
            DataTemplate itemTemplateHeader = null;
            if (this.ItemTemplateHeaderSelector != null)
            {
                itemTemplateHeader = this.ItemTemplateHeaderSelector.SelectTemplate(obj2, tileViewItem);
            }
            if (this.ItemTemplateHeader != null)
            {
                itemTemplateHeader = this.ItemTemplateHeader;
            }
            if (tileViewItem == item)
            {
                if (tileViewItem.HeaderTemplateSelector != null)
                {
                    itemTemplateHeader = tileViewItem.HeaderTemplateSelector.SelectTemplate(obj2, tileViewItem);
                }
                if (tileViewItem.HeaderTemplate != null)
                {
                    itemTemplateHeader = tileViewItem.HeaderTemplate;
                }
            }
            return itemTemplateHeader;
        }

        private DataTemplate GetMaximizedItemDataTemplate(TileViewItem tileViewItem, object item)
        {
            object obj2 = (tileViewItem == item) ? tileViewItem.Content : item;
            DataTemplate itemTemplateMaximized = null;
            if (this.ItemTemplateMaximizedSelector != null)
            {
                itemTemplateMaximized = this.ItemTemplateMaximizedSelector.SelectTemplate(obj2, tileViewItem);
            }
            if (this.ItemTemplateMaximized != null)
            {
                itemTemplateMaximized = this.ItemTemplateMaximized;
            }
            if (tileViewItem == item)
            {
                if (tileViewItem.ContentTemplateMaximizedSelector != null)
                {
                    itemTemplateMaximized = tileViewItem.ContentTemplateMaximizedSelector.SelectTemplate(obj2, tileViewItem);
                }
                if (tileViewItem.ContentTemplateMaximized != null)
                {
                    itemTemplateMaximized = tileViewItem.ContentTemplateMaximized;
                }
            }
            return itemTemplateMaximized;
        }

        private DataTemplate GetMinimizedItemDataTemplate(TileViewItem tileViewItem, object item)
        {
            object obj2 = (tileViewItem == item) ? tileViewItem.Content : item;
            DataTemplate itemTemplateMinimized = null;
            if (this.ItemTemplateMinimizedSelector != null)
            {
                itemTemplateMinimized = this.ItemTemplateMinimizedSelector.SelectTemplate(obj2, tileViewItem);
            }
            if (this.ItemTemplateMinimized != null)
            {
                itemTemplateMinimized = this.ItemTemplateMinimized;
            }
            if (tileViewItem == item)
            {
                if (tileViewItem.ContentTemplateMinimizedSelector != null)
                {
                    itemTemplateMinimized = tileViewItem.ContentTemplateMinimizedSelector.SelectTemplate(obj2, tileViewItem);
                }
                if (tileViewItem.ContentTemplateMinimized != null)
                {
                    itemTemplateMinimized = tileViewItem.ContentTemplateMinimized;
                }
            }
            return itemTemplateMinimized;
        }

        internal int IndexFromTileViewItem(TileViewItem item)
        {
            if (item == null)
            {
                return -1;
            }
            int index = base.Items.IndexOf(item);
            if (index != -1)
            {
                return index;
            }
            return base.ItemContainerGenerator.IndexFromContainer(item);
        }

        protected override bool IsItemItsOwnContainerOverride(object item)
        {
            return (item is TileViewItem);
        }

        private void OnAfterApplyTemplate()
        {
            for (int i = 0; i < base.Items.Count; i++)
            {
                TileViewItem item = this.TileViewItemFromIndex(i);
                if (item != null)
                {
                    item.FontFamily = base.FontFamily;
                }
            }
        }

        public override void OnApplyTemplate()
        {
            string str = string.Empty;
            base.OnApplyTemplate();
            this._isLoaded = true;
            if (!string.IsNullOrEmpty(str))
            {
                this._isLoaded = false;
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to TileView.\nDetails: {0}", new object[] { str }));
                }
            }
            else
            {
                this.OnAfterApplyTemplate();
            }
        }

        private void OnColumnsChanged(int oldValue)
        {
            if (this.Panel != null)
            {
                this.Panel.InvalidateMeasure();
            }
        }

        private static void OnColumnsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TileView view = d as TileView;
            int oldValue = (int)e.OldValue;
            view.OnColumnsChanged(oldValue);
        }

        protected override AutomationPeer OnCreateAutomationPeer()
        {
            if (this._peer == null)
            {
                this._peer = AutomationPeerFactory.CreateAutomationPeer(this, typeof(TileView));
            }
            if (this._peer == null)
            {
                return base.OnCreateAutomationPeer();
            }
            return this._peer;
        }

        protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
        {
            base.OnItemsChanged(e);
            this.MaximizedIndex = base.Items.IndexOf(this.MaximizedItem);
            for (int i = 0; i < base.Items.Count; i++)
            {
                TileViewItem item = base.Items[i] as TileViewItem;
                if ((item != null) && (item.TiledState == TiledState.Maximized))
                {
                    this.MaximizedIndex = i;
                }
            }
            if (this.MaximizedIndex == -1)
            {
                for (int j = 0; j < base.Items.Count; j++)
                {
                    TileViewItem item2 = base.Items[j] as TileViewItem;
                    if (item2 != null)
                    {
                        item2.TiledState = TiledState.Tiled;
                    }
                }
            }
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    if ((this.GrabbedIndex != -1) && (e.NewStartingIndex <= this.GrabbedIndex))
                    {
                        this.GrabbedIndex += e.NewItems.Count;
                    }
                    this.Ranking.OnAdded(e.NewStartingIndex, e.NewItems.Count);
                    goto Label_023E;

                case NotifyCollectionChangedAction.Remove:
                    if ((this.GrabbedIndex != -1) && (e.OldStartingIndex <= this.GrabbedIndex))
                    {
                        if (this.GrabbedIndex >= (e.OldStartingIndex + e.OldItems.Count))
                        {
                            this.GrabbedIndex -= e.OldItems.Count;
                            break;
                        }
                        this.GrabbedIndex = -1;
                    }
                    break;

                case NotifyCollectionChangedAction.Replace:
                    this.GrabbedIndex = -1;
                    goto Label_023E;

                case NotifyCollectionChangedAction.Reset:
                    this.GrabbedIndex = -1;
                    this.Ranking.OnReset(base.Items.Count);
                    goto Label_023E;

                default:
                    goto Label_023E;
            }
            this.Ranking.OnRemoved(e.OldStartingIndex, e.OldItems.Count);
            if (this.Panel != null)
            {
                for (int k = 1; k < this.Panel.Children.Count; k++)
                {
                    bool flag = false;
                    for (int m = 0; m < base.Items.Count; m++)
                    {
                        TileViewItem item3 = (TileViewItem)base.ItemContainerGenerator.ContainerFromIndex(m);
                        if (item3 == ((TileViewItem)this.Panel.Children[k]))
                        {
                            flag = true;
                            break;
                        }
                    }
                    if (!flag)
                    {
                        this.Panel.RemoveInternalChildRange(k, e.OldItems.Count);
                        break;
                    }
                }
            }
        Label_023E:
            this.UpdateTiledState();
            if (this.Panel != null)
            {
                this.Panel.InvalidateMeasure();
            }
        }

        private void OnMaximizedIndexChanged(int oldValue)
        {
            if ((this.MaximizedIndex < 0) || (base.Items.Count <= this.MaximizedIndex))
            {
                this.MaximizedIndex = -1;
                this.MaximizedItem = null;
            }
            else
            {
                this.MaximizedItem = base.Items[this.MaximizedIndex];
            }
            this.UpdateTiledState();
        }

        private static void OnMaximizedIndexPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TileView sender = d as TileView;
            int oldValue = (int)e.OldValue;
            sender.OnMaximizedIndexChanged(oldValue);
            if ((sender.MaximizedIndexChanged != null) && sender._throwMaximizedIndexChanged)
            {
                PropertyChangedEventArgs<int> args = new PropertyChangedEventArgs<int>
                {
                    OldValue = (int)e.OldValue,
                    NewValue = (int)e.NewValue
                };
                sender.MaximizedIndexChanged(sender, args);
            }
        }

        private void OnMaximizedItemChanged(object oldValue)
        {
            this.MaximizedIndex = base.Items.IndexOf(this.MaximizedItem);
            this.UpdateTiledState();
        }

        private static void OnMaximizedItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TileView sender = d as TileView;
            object oldValue = e.OldValue;
            sender.OnMaximizedItemChanged(oldValue);
            if ((sender.MaximizedItemChanged != null) && sender._throwMaximizedItemChanged)
            {
                PropertyChangedEventArgs<object> args = new PropertyChangedEventArgs<object>
                {
                    OldValue = e.OldValue,
                    NewValue = e.NewValue
                };
                sender.MaximizedItemChanged(sender, args);
            }
        }

        private void OnMinimizedItemsPositionChanged(Dock oldValue)
        {
            if (this.Panel != null)
            {
                this.Panel.InvalidateMeasure();
            }
        }

        private static void OnMinimizedItemsPositionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TileView view = d as TileView;
            Dock oldValue = (Dock)e.OldValue;
            view.OnMinimizedItemsPositionChanged(oldValue);
        }

        private void OnRowsChanged(int oldValue)
        {
            if (this.Panel != null)
            {
                this.Panel.InvalidateMeasure();
            }
        }

        private static void OnRowsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TileView view = d as TileView;
            int oldValue = (int)e.OldValue;
            view.OnRowsChanged(oldValue);
        }

        private void OnScrollBarStyleChanged(Style oldValue)
        {
            if (this.Panel != null)
            {
                this.Panel.InvalidateMeasure();
            }
        }

        private static void OnScrollBarStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TileView view = d as TileView;
            Style oldValue = (Style)e.OldValue;
            view.OnScrollBarStyleChanged(oldValue);
        }

        private void OnScrollBarVisibilityChanged(ScrollBarVisibility oldValue)
        {
            if (this.Panel != null)
            {
                this.Panel.InvalidateMeasure();
            }
        }

        private static void OnScrollBarVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TileView view = d as TileView;
            ScrollBarVisibility oldValue = (ScrollBarVisibility)e.OldValue;
            view.OnScrollBarVisibilityChanged(oldValue);
        }

        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            base.PrepareContainerForItemOverride(element, item);
            TileViewItem tileViewItem = (TileViewItem)element;
            tileViewItem.isPrepared = true;
            tileViewItem.TileView = this;
            tileViewItem.LastFinalRect = null;
            if (item != tileViewItem)
            {
                tileViewItem.ContentMaximized = item;
                tileViewItem.ContentMinimized = item;
                if (!(item is FrameworkElement))
                {
                    tileViewItem.Header = item;
                }
                tileViewItem.ContentTemplate = this.GetItemDataTemplate(tileViewItem, item);
                tileViewItem.HeaderTemplate = this.GetItemHeaderDataTemplate(tileViewItem, item);
                tileViewItem.ContentTemplateMaximized = this.GetMaximizedItemDataTemplate(tileViewItem, item);
                tileViewItem.ContentTemplateMinimized = this.GetMinimizedItemDataTemplate(tileViewItem, item);
                if (this.MaximizedIndex == -1)
                {
                    tileViewItem.TiledState = TiledState.Tiled;
                }
                else if (this.MaximizedIndex == base.Items.IndexOf(item))
                {
                    tileViewItem.TiledState = TiledState.Maximized;
                }
                else
                {
                    tileViewItem.TiledState = TiledState.Minimized;
                }
            }
            tileViewItem.UpdatePresenter();
            tileViewItem.SetBinding<TileView>(Control.BackgroundProperty, this, m => m.ItemBackground);
            tileViewItem.SetBinding<TileView>(Control.ForegroundProperty, this, m => m.ItemForeground);
            tileViewItem.SetBinding<TileView>(Control.BorderBrushProperty, this, m => m.BorderBrush);
            tileViewItem.SetBinding<TileView>(Control.BorderThicknessProperty, this, m => m.BorderThickness);
            tileViewItem.SetBinding<TileView>(HeaderedContentControl.HeaderBackgroundProperty, this, m => m.HeaderBackground);
            tileViewItem.SetBinding<TileView>(HeaderedContentControl.HeaderForegroundProperty, this, m => m.HeaderForeground);
            tileViewItem.SetBinding<TileView>(TileViewItem.MouseOverBrushProperty, this, m => m.MouseOverBrush);
            tileViewItem.SetBinding<TileView>(TileViewItem.PressedBrushProperty, this, m => m.PressedBrush);
            tileViewItem.SetBinding<TileView>(TileViewItem.FocusBrushProperty, this, m => m.FocusBrush);
            tileViewItem.TryReCaptureMouse();
        }

        private void SetCustomDefaultValues()
        {
            base.MouseLeftButtonUp += delegate(object param0, MouseButtonEventArgs param1)
            {
                base.ReleaseMouseCapture();
                this.GrabbedIndex = -1;
            };
        }

        internal TileViewItem TileViewItemFromIndex(int index)
        {
            TileViewItem item = base.Items[index] as TileViewItem;
            if (item != null)
            {
                return item;
            }
            return (TileViewItem)base.ItemContainerGenerator.ContainerFromIndex(index);
        }

        internal TileViewItem TileViewItemFromItem(object item)
        {
            TileViewItem item2 = item as TileViewItem;
            if (item2 != null)
            {
                return item2;
            }
            return (TileViewItem)base.ItemContainerGenerator.ContainerFromItem(item);
        }

        private void UpdateTiledState()
        {
            this.ShouldAnimate = true;
            for (int i = 0; i < base.Items.Count; i++)
            {
                TileViewItem item = this.TileViewItemFromIndex(i);
                if (item != null)
                {
                    if (this.MaximizedIndex == -1)
                    {
                        item.TiledState = TiledState.Tiled;
                    }
                    else if (this.MaximizedIndex == i)
                    {
                        item.TiledState = TiledState.Maximized;
                    }
                    else
                    {
                        item.TiledState = TiledState.Minimized;
                    }
                }
            }
        }

        // Properties
        public TimeSpan AnimationDuration
        {
            get { return (TimeSpan)GetValue(AnimationDurationProperty); }
            set { SetValue(AnimationDurationProperty, value); }
        }

        public IEasingFunction AnimationEasingFunction
        {
            get { return (IEasingFunction)GetValue(AnimationEasingFunctionProperty); }
            set { SetValue(AnimationEasingFunctionProperty, value); }
        }

        public Brush ButtonBackground
        {
            get { return (Brush)GetValue(ButtonBackgroundProperty); }
            set { SetValue(ButtonBackgroundProperty, value); }
        }

        public Brush ButtonForeground
        {
            get { return (Brush)GetValue(ButtonForegroundProperty); }
            set { SetValue(ButtonForegroundProperty, value); }
        }

        public bool CanUserReorder
        {
            get { return (bool)GetValue(CanUserReorderProperty); }
            set { SetValue(CanUserReorderProperty, value); }
        }

        public int Columns
        {
            get { return (int)GetValue(ColumnsProperty); }
            set { SetValue(ColumnsProperty, value); }
        }

        public Brush FocusBrush
        {
            get { return (Brush)GetValue(FocusBrushProperty); }
            set { SetValue(FocusBrushProperty, value); }
        }

        public Brush HeaderBackground
        {
            get { return (Brush)GetValue(HeaderBackgroundProperty); }
            set { SetValue(HeaderBackgroundProperty, value); }
        }

        public Brush HeaderForeground
        {
            get { return (Brush)GetValue(HeaderForegroundProperty); }
            set { SetValue(HeaderForegroundProperty, value); }
        }

        public Brush ItemBackground
        {
            get { return (Brush)GetValue(ItemBackgroundProperty); }
            set { SetValue(ItemBackgroundProperty, value); }
        }

        public Brush ItemForeground
        {
            get { return (Brush)GetValue(ItemForegroundProperty); }
            set { SetValue(ItemForegroundProperty, value); }
        }

        public DataTemplate ItemTemplateHeader
        {
            get { return (DataTemplate)GetValue(ItemTemplateHeaderProperty); }
            set { SetValue(ItemTemplateHeaderProperty, value); }
        }

        public DataTemplateSelector ItemTemplateHeaderSelector
        {
            get { return (DataTemplateSelector)GetValue(ItemTemplateHeaderSelectorProperty); }
            set { SetValue(ItemTemplateHeaderSelectorProperty, value); }
        }

        public DataTemplate ItemTemplateMaximized
        {
            get { return (DataTemplate)GetValue(ItemTemplateMaximizedProperty); }
            set { SetValue(ItemTemplateMaximizedProperty, value); }
        }

        public DataTemplateSelector ItemTemplateMaximizedSelector
        {
            get { return (DataTemplateSelector)GetValue(ItemTemplateMaximizedSelectorProperty); }
            set { SetValue(ItemTemplateMaximizedSelectorProperty, value); }
        }

        public DataTemplate ItemTemplateMinimized
        {
            get { return (DataTemplate)GetValue(ItemTemplateMinimizedProperty); }
            set { SetValue(ItemTemplateMinimizedProperty, value); }
        }

        public DataTemplateSelector ItemTemplateMinimizedSelector
        {
            get { return (DataTemplateSelector)GetValue(ItemTemplateMinimizedSelectorProperty); }
            set { SetValue(ItemTemplateMinimizedSelectorProperty, value); }
        }

        public DataTemplateSelector ItemTemplateSelector
        {
            get { return (DataTemplateSelector)GetValue(ItemTemplateSelectorProperty); }
            set { SetValue(ItemTemplateSelectorProperty, value); }
        }

        public int MaximizedIndex
        {
            get { return (int)GetValue(MaximizedIndexProperty); }
            set { SetValue(MaximizedIndexProperty, value); }
        }

        public object MaximizedItem
        {
            get { return GetValue(MaximizedItemProperty); }
            set { SetValue(MaximizedItemProperty, value); }
        }

        public Dock MinimizedItemsPosition
        {
            get { return (Dock)GetValue(MinimizedItemsPositionProperty); }
            set { SetValue(MinimizedItemsPositionProperty, value); }
        }

        public Brush MouseOverBrush
        {
            get { return (Brush)GetValue(MouseOverBrushProperty); }
            set { SetValue(MouseOverBrushProperty, value); }
        }

        public Brush PressedBrush
        {
            get { return (Brush)GetValue(PressedBrushProperty); }
            set { SetValue(PressedBrushProperty, value); }
        }

        public int Rows
        {
            get { return (int)GetValue(RowsProperty); }
            set { SetValue(RowsProperty, value); }
        }

        public Style ScrollBarStyle
        {
            get { return (Style)GetValue(ScrollBarStyleProperty); }
            set { SetValue(ScrollBarStyleProperty, value); }
        }

        public ScrollBarVisibility ScrollBarVisibility
        {
            get { return (ScrollBarVisibility)GetValue(ScrollBarVisibilityProperty); }
            set { SetValue(ScrollBarVisibilityProperty, value); }
        }

        public bool UpdateSourceCollection
        {
            get { return (bool)GetValue(UpdateSourceCollectionProperty); }
            set { SetValue(UpdateSourceCollectionProperty, value); }
        }
    }
}
